﻿namespace JunFan.Tests.UnitTests
{
    using System;
    using Domain;
    using FluentAssertions;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Infrastructure;

    [TestClass]
    public class StartingItems
    {
        [TestInitialize]
        public void InitializeBoard()
        {
            UnitTestContext.InitBoard();
        }

        /// <summary>
        /// Given: An added item, not started and neither completed
        /// When: The item is started
        /// Then: Start date equals Today
        /// </summary>
        [TestMethod]
        public void WithoutStartDateShouldBeStartedWithStartDateEqualsToday()
        {
            var item = Given.NewItem.Added(UnitTestContext.Board);

            Item startedItem = When.StartingItem(item.InternalId);

            startedItem.StartedOn.Should().Be(DateTime.Today);
        }

        /// <summary>
        /// Given: An added item, not started and neither completed
        /// When: The item is started with a start date
        /// Then: Start date equals the given date
        /// </summary>
        [TestMethod]
        public void WithStartDateShouldBeStartedWithStartDate()
        {
            DateTime expectedStartDate = DateTime.Today.AddDays(-2);

            var item = Given.NewItem.Added(UnitTestContext.Board);

            Item startedItem = When.StartingItem(item.InternalId, expectedStartDate);

            startedItem.StartedOn.Should().Be(expectedStartDate);
        }

        /// <summary>
        /// Given: A item id that doesnt exist
        /// When: Starting it
        /// Then: A WrongArgumentException exception is throw
        /// </summary>
        [TestMethod]
        public void ShouldFailIfItemIdDoesntExist()
        {
            int nonExistentId = Given.ItemIdThatDoesntExist;

            Action action = () => When.StartingItem(nonExistentId);

            // Then
            action.ShouldThrow<WrongArgumentException>()
                  .WithMessage(string.Format("There isn't an Item with id '{0}'.", nonExistentId), ComparisonMode.EquivalentSubstring);
        }

        /// <summary>
        /// Given: A completed item
        /// When: Starting it
        /// Then: A Business rule exception is throw
        /// </summary>
        [TestMethod]
        public void ShouldFailIfItemIsCompleted()
        {
            var completedItem = Given.CompletedItem.Added(UnitTestContext.Board);

            Action action = () => When.StartingItem(completedItem.InternalId);

            // Then
            action.ShouldThrow<BusinessRuleException>()
                  .WithMessage("You cannot start an item that is already completed.", ComparisonMode.EquivalentSubstring);
        }
    }
}
